package com.beemans.admob.ads;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class AbAdvertLoadManager {
    private final Map<String, AbSplashAdWrapper> splashAdWrapperMap = new ConcurrentHashMap<>();
    private final Map<String, AbInsertAdWrapper> insertAdWrapperMap = new ConcurrentHashMap<>();
    private final Map<String, AbRewardAdWrapper> rewardAdWrapperMap = new ConcurrentHashMap<>();

    private final List<AbNativeAdWrapper> nativeAdReadyList = new CopyOnWriteArrayList<>();
    private final List<AbNativeAdWrapper> nativeAdLoadingList = new CopyOnWriteArrayList<>();

    private final Object nativeAdLock = new Object();

    private AbAdvertLoadManager() {
    }

    private static final class Holder {
        private static final AbAdvertLoadManager INSTANCE = new AbAdvertLoadManager();
    }

    public static AbAdvertLoadManager getInstance() {
        return Holder.INSTANCE;
    }

    public boolean isNativeAdvertReady(@NonNull String placementId) {
        return nativeAdReadyList.stream()
                .anyMatch(adWrapper -> Objects.equals(adWrapper.getPlacementId(), placementId) && adWrapper.isAdvertReady());
    }

    public boolean isNativeAdvertLoading(@NonNull String placementId) {
        return nativeAdLoadingList.stream()
                .anyMatch(adWrapper -> Objects.equals(adWrapper.getPlacementId(), placementId) && adWrapper.isAdvertLoading());
    }

    @NonNull
    public AbSplashAdWrapper getSplashAdWrapper(@NonNull String placementId) {
        AbSplashAdWrapper splashAdWrapper = splashAdWrapperMap.get(placementId);
        //noinspection Java8MapApi
        if (splashAdWrapper == null) {
            splashAdWrapper = new AbSplashAdWrapper(placementId);
            splashAdWrapperMap.put(placementId, splashAdWrapper);
        }
        return splashAdWrapper;
    }

    @NonNull
    public AbInsertAdWrapper getInsertAdWrapper(@NonNull String placementId) {
        AbInsertAdWrapper insertAdWrapper = insertAdWrapperMap.get(placementId);
        //noinspection Java8MapApi
        if (insertAdWrapper == null) {
            insertAdWrapper = new AbInsertAdWrapper(placementId);
            insertAdWrapperMap.put(placementId, insertAdWrapper);
        }
        return insertAdWrapper;
    }

    @NonNull
    public AbRewardAdWrapper getRewardAdWrapper(@NonNull String placementId) {
        AbRewardAdWrapper rewardAdWrapper = rewardAdWrapperMap.get(placementId);
        //noinspection Java8MapApi
        if (rewardAdWrapper == null) {
            rewardAdWrapper = new AbRewardAdWrapper(placementId);
            rewardAdWrapperMap.put(placementId, rewardAdWrapper);
        }
        return rewardAdWrapper;
    }

    @Nullable
    public AbNativeAdWrapper getReadyNativeAdWrapper(@NonNull String placementId) {
        return nativeAdReadyList.stream()
                .filter(adWrapper -> Objects.equals(adWrapper.getPlacementId(), placementId) && adWrapper.isAdvertReady())
                .findFirst()
                .orElse(null);
    }

    public void updateNativeReadyList(@NonNull AbNativeAdWrapper adWrapper, boolean isRemove) {
        synchronized (nativeAdLock) {
            if (isRemove) {
                nativeAdReadyList.remove(adWrapper);
            } else if (!nativeAdReadyList.contains(adWrapper)) {
                nativeAdReadyList.add(adWrapper);
            }
        }
    }

    public void updateNativeLoadingList(@NonNull AbNativeAdWrapper adWrapper, boolean isRemove) {
        synchronized (nativeAdLock) {
            if (isRemove) {
                nativeAdLoadingList.remove(adWrapper);
            } else if (!nativeAdLoadingList.contains(adWrapper)) {
                nativeAdLoadingList.add(adWrapper);
            }
        }
    }
}